﻿using System.ComponentModel.DataAnnotations;
using System.Threading.Channels;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;

namespace OpenPasteSpider
{
    public partial class ChannelHelper : ISingletonDependency
    {


        //private Channel<ChannelModel> mqlist;

        /// <summary>
        /// 发布的任务计划，执行哪一个任务等
        /// </summary>
        private Channel<ChannelPlan> _channelorder;


        /// <summary>
        /// 监听对象变更，比如服务器的内存警告调整，最低运行数调整等
        /// </summary>
        private Channel<ChannelMonitorModel> _channelmonitor;

        //private Channel<NoticeLogAddDto> _channelnotice;

        /// <summary>
        /// 节点状态变更 master选举等
        /// </summary>
        private Channel<SlaveEventModel> _channelslaveevent;

        /// <summary>
        /// 消息通知，升级成功，升级失败等
        /// </summary>
        private Channel<SlaveNoticeItem> _channelslavenotice;

        /// <summary>
        /// 
        /// </summary>
        public ChannelHelper()
        {
            //_config = config.Value;
            _channelslaveevent = Channel.CreateBounded<SlaveEventModel>(1000);
            _channelslavenotice = Channel.CreateBounded<SlaveNoticeItem>(1000);
            _channelorder = Channel.CreateBounded<ChannelPlan>(1000);
            _channelmonitor = Channel.CreateBounded<ChannelMonitorModel>(1000);
        }


        /// <summary>
        /// 写入执行计划 command
        /// </summary>
        /// <param name="planid"></param>
        /// <param name="linuxid"></param>
        public void WritePlanCommand(int planid, int linuxid)
        {
            _channelorder.Writer.WriteAsync(new ChannelPlan() { linuxid = linuxid, planid = planid });
        }

        /// <summary>
        /// 写入计划 command
        /// </summary>
        /// <param name="info"></param>
        public void WriteSlaveCommand(ChannelPlan info)
        {
            _channelorder.Writer.WriteAsync(info);
        }

        /// <summary>
        /// 写入配置变更监听变更 monitor
        /// </summary>
        /// <param name="model"></param>
        public async void WriteMonitor(ChannelMonitorModel model)
        {
            await _channelmonitor.Writer.WriteAsync(model);
        }

        /// <summary>
        /// 写入集群事件 action
        /// </summary>
        /// <param name="input"></param>
        public async void WriteSlaveAction(SlaveEventModel input)
        {
            //if (!_config.SingleModel)
            //{
            // input.FromNodeId = MySlaveNodeId;
            await _channelslaveevent.Writer.WriteAsync(input);
            //}
        }

        /// <summary>
        /// 写入集群消息 某某升级等 notify
        /// </summary>
        /// <param name="input"></param>
        public async void WriteSlaveNotice(SlaveNoticeItem input)
        {
            // if (!_config.SingleModel)
            // {
            await _channelslavenotice.Writer.WriteAsync(input);
            // }
        }

        /// <summary>
        /// 执行计划
        /// </summary>
        public Channel<ChannelPlan> CommandPlanChannel { get { return _channelorder; } }

        /// <summary>
        /// 
        /// </summary>
        public Channel<ChannelMonitorModel> ChannelMonitor { get { return _channelmonitor; } }

        /// <summary>
        /// 
        /// </summary>
        public Channel<SlaveEventModel> ChannelSlave { get { return _channelslaveevent; } }

        /// <summary>
        /// 
        /// </summary>
        public Channel<SlaveNoticeItem> ChannelNotice { get { return _channelslavenotice; } }
    }


    /// <summary>
    /// 
    /// </summary>
    public class SlaveEventModel : SlaveBase
    {
        /// <summary>
        /// status stopmaster startmaster
        /// </summary>
        public SlaveEventCode Event { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Object { get; set; }


    }

    /// <summary>
    /// 节点基础消息字段
    /// </summary>
    public class SlaveBase
    {
        /// <summary>
        /// 发送往哪个节点 master有时候也会行使Node的功能
        /// </summary>
        public int ToNodeId { get; set; } = 0;

        /// <summary>
        /// 管理员是否已经处理 处理后的表示直接给节点执行，否则应该是发送给master进行处理
        /// </summary>
        public bool MasterHandler { get; set; } = false;

        /// <summary>
        /// 是否来源HTTPAPI 否则是内部产生
        /// </summary>
        public bool FromApi { get; set; } = false;
    }

    /// <summary>
    /// 
    /// </summary>
    public enum SlaveEventCode
    {
        /// <summary>
        /// 状态变更
        /// </summary>
        status,
        /// <summary>
        /// 失去管理员
        /// </summary>
        stopmaster,
        /// <summary>
        /// 成为管理员
        /// </summary>
        startmaster,
        /// <summary>
        /// 通知选举
        /// </summary>
        votemaster,
        /// <summary>
        /// 通知节点添加linux
        /// </summary>
        linuxadd,
        /// <summary>
        /// 服务器信息变更，一般是变更密码和证书等
        /// </summary>
        linuxupdate,
        /// <summary>
        /// 通知节点移除linux
        /// </summary>
        linuxremove,
        /// <summary>
        /// 节点新增
        /// </summary>
        nodeadd,
        /// <summary>
        /// 节点更新
        /// </summary>
        nodeupdate,
        /// <summary>
        /// 节点停止移除
        /// </summary>
        noderemove

    }

    /// <summary>
    /// 推送消息信息体
    /// </summary>
    public class SlaveNoticeItem : SlaveBase
    {

        ///<summary>
        ///消息代码
        ///</summary>
        [MaxLength(16)]
        public string Code { get; set; }

        ///<summary>
        ///事件对象ID
        ///</summary>
        public int ObjId { get; set; }

        ///<summary>
        ///消息正文
        ///</summary>
        public string Body { get; set; }

        ///<summary>
        ///发生次数 0表示标记，不推送
        ///</summary>
        public int Time { get; set; } = 0;
    }

    /// <summary>
    /// 
    /// </summary>
    public class ChannelPlan : SlaveBase
    {

        /// <summary>
        /// 计划ID
        /// </summary>
        public int planid { get; set; }
        /// <summary>
        /// 执行对象
        /// </summary>
        public int linuxid { get; set; }


    }


    /// <summary>
    /// 
    /// </summary>
    public class ChannelMonitorModel : SlaveBase
    {

        /// <summary>
        /// 是否是monitor模式，还是监听数量限定模式
        /// </summary>
        public bool BoolMonitor { get; set; } = false;

        /// <summary>
        /// 涉及哪台服务器
        /// </summary>
        public int LinuxId { get; set; }

        /// <summary>
        /// 为0的时候表示监听服务器的内存和CPU 不为0表示监听某一个服务的状态
        /// </summary>
        public int ServiceId { get; set; } = 0;
        /// <summary>
        /// 
        /// </summary>
        public string ModelCode { get; set; } = "default";

    }

}
